package org.jacquesh.mall.common.model;

import lombok.Data;

import java.io.Serializable;
import java.util.Map;

/**
 * @author Jacquesh
 * @version 1.0
 * @date 2020/9/26 0:52
 */

public class JsResult<T> implements Serializable {
    /**
     * 默认操作成功
     */
    private static final JsError DEFAULT_SUCCESS = JsError.Default.SUCCESS;

    /**
     * 默认操作失败
     */
    private static final JsError DEFAULT_ERROR = JsError.Default.ERROR_COMMON_EXCEPTION;

    /**
     * 响应码
     */
    private String code;

    /**
     * 响应码描述信息
     */
    private String message;

    /**
     * 响应结果状态，{@code true} 表示成功；{@code false} 表示失败
     */
    private Boolean success = false;

    /**
     * 追溯ID
     */
//    @JsonProperty("trace_id")
    private String traceId;

    /** 请求码 */
    private String requestId;

    /**
     * 响应头：可以存放请求相关的信息
     */
    private Map<String, String> header;

    /**
     * 响应体
     */
    private T body;

    public JsResult() {
    }

    /**
     * 构造方法
     *
     * @param code    返回码
     * @param message 描述信息
     * @param success 操作结果，true / false
     * @param traceId 追溯码
     * @param header  响应头
     * @param body    响应体
     */
    public JsResult(String code, String message, Boolean success, String traceId, Map<String, String> header, T body) {
        this.code = code;
        this.message = message;
        this.success = success;
        this.traceId = traceId;
        this.header = header;
        this.body = body;
    }

    /**
     * 构造方法
     *
     * @param code    返回码
     * @param message 描述信息
     * @param success 操作结果，true / false
     * @param body    响应体
     */
    public JsResult(String code, String message, Boolean success, T body) {
        this.code = code;
        this.message = message;
        this.success = success;
        this.body = body;
    }

    /**
     * 构造方法
     *
     * @param iError  {@link JsError}
     * @param success 操作结果，true / false
     * @param body    响应体
     */
    public JsResult(JsError iError, Boolean success, T body) {
        this.code = iError.getCode();
        this.message = iError.getMessage();
        this.success = success;
        this.body = body;
    }

    /**
     * 操作成功
     *
     * @param <T> 响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> ok() {
        return new JsResult<T>()
                .setSuccess(true)
                .setCode(DEFAULT_SUCCESS.getCode())
                .setMessage(DEFAULT_SUCCESS.getMessage());
    }

    /**
     * 操作成功
     *
     * @param body 响应体
     * @param <T>  响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> ok(T body) {
        return new JsResult<T>()
                .setSuccess(true)
                .setCode(DEFAULT_SUCCESS.getCode())
                .setMessage(DEFAULT_SUCCESS.getMessage())
                .setBody(body);
    }

    /**
     * 操作成功
     *
     * @param code    响应码
     * @param message 响应信息
     * @param <T>     响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> ok(String code, String message) {
        return new JsResult<T>()
                .setSuccess(true)
                .setCode(code)
                .setMessage(message);
    }

    /**
     * 操作成功
     *
     * @param code    响应码
     * @param message 响应信息
     * @param body    响应体
     * @param <T>     响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> ok(String code, String message, T body) {
        return new JsResult<T>()
                .setSuccess(true)
                .setCode(code)
                .setMessage(message)
                .setBody(body);
    }

    /**
     * 操作失败
     *
     * @param <T> 响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> error() {
        return new JsResult<T>()
                .setCode(DEFAULT_ERROR.getCode())
                .setMessage(DEFAULT_ERROR.getMessage());
    }

    /**
     * 操作失败
     *
     * @param message 响应信息
     * @param <T>     响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> error(String message) {
        return new JsResult<T>()
                .setCode(DEFAULT_ERROR.getCode())
                .setMessage(message);
    }

    /**
     * 操作失败
     *
     * @param code    响应码
     * @param message 响应信息
     * @param <T>     响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> error(String code, String message) {
        return new JsResult<T>()
                .setCode(code)
                .setMessage(message);
    }

    /**
     * 操作失败
     *
     * @param error {@link JsError}
     * @param <T>   响应体类型
     * @return 响应封装类 {@link JsResult}
     */
    public static <T> JsResult<T> error(JsError error) {
        return new JsResult<T>()
                .setCode(error.getCode())
                .setMessage(error.getMessage());
    }

    /**
     * {@code code} 的get方法
     *
     * @return {@code code} 的值
     */
    public String getCode() {
        return code;
    }

    /**
     * {@code code} 的get方法
     *
     * @param code 响应码
     * @return {@link JsResult}
     */
    public JsResult setCode(String code) {
        this.code = code;
        return this;
    }

    /**
     * {@code message} 的get方法
     *
     * @return {@code message} 的值
     */
    public String getMessage() {
        return message;
    }

    /**
     * {@code message} 的get方法
     *
     * @param message 响应信息
     * @return {@link JsResult}
     */
    public JsResult setMessage(String message) {
        this.message = message;
        return this;
    }

    /**
     * {@code success} 的get方法
     *
     * @return {@code success} 的值
     */
    public Boolean getSuccess() {
        return success;
    }

    /**
     * {@code success} 的get方法
     *
     * @param success 操作结果
     * @return {@link JsResult}
     */
    public JsResult setSuccess(Boolean success) {
        this.success = success;
        return this;
    }

    /**
     * {@code traceId} 的get方法
     *
     * @return {@code traceId} 的值
     */
    public String getTraceId() {
        return traceId;
    }

    /**
     * {@code traceId} 的get方法
     *
     * @param traceId 追溯码
     * @return {@link JsResult}
     */
    public JsResult setTraceId(String traceId) {
        this.traceId = traceId;
        return this;
    }

    /**
     * {@code header} 的get方法
     *
     * @return {@code header} 的值
     */
    public Map<String, String> getHeader() {
        return header;
    }

    /**
     * {@code header} 的get方法
     *
     * @param header 响应头
     * @return {@link JsResult}
     */
    public JsResult setHeader(Map<String, String> header) {
        this.header = header;
        return this;
    }

    /**
     * {@code body} 的get方法
     *
     * @return {@code body} 的值
     */
    public T getBody() {
        return body;
    }

    /**
     * {@code body} 的get方法
     *
     * @param body 响应体
     * @return {@link JsResult}
     */
    public JsResult setBody(T body) {
        this.body = body;
        return this;
    }

    /**
     * {@code requestId} 的get方法
     *
     * @return {@code requestId} 的值
     */
    public String getRequestId() {
        return requestId;
    }

    /**
     * {@code requestId} 的get方法
     *
     * @param requestId 响应体
     * @return {@link JsResult}
     */
    public JsResult setRequestId(String requestId) {
        this.requestId = requestId;
        return this;
    }
}
